﻿#include "ssLeSession.h"
#include "message/ssMsgIdDef.h"
#include "message/ssNetMsgHead.h"
#include "ssLeServer.h"
#include <memory.h>

namespace StarSeeker
{

ssLeSession::ssLeSession()
{
	m_timeCheck = false;
	m_buffer = 0;
	m_fd = 0;
	m_lastTime = 0;
	m_fastCount = 0;
	m_pServer = 0;
	m_checkCount = 40;
	m_intervalTime = 100;
	m_sessionID = 0;
	m_isConnect = false;
}
ssLeSession::~ssLeSession()
{
	Close();
}

void ssLeSession::Init(ssLeServer* pServer, u32 id, bufferevent* buf, evutil_socket_t fd, sockaddr* addr)
{
	Close();
	m_sessionID = id;
	m_pServer = pServer;
	m_lastTime = 0;
	m_fastCount = 0;
	m_buffer = buf;
	m_fd = fd;
	memcpy(&m_addr, addr, sizeof(sockaddr));
	m_isConnect = true;
}

void ssLeSession::SetTimeCheck(bool timeCheck, i64 intervalTime, u16 checkCount)
{
	m_timeCheck = timeCheck;
	m_intervalTime = intervalTime;
	m_checkCount = checkCount;
}

bool ssLeSession::SendData(const void* data, const u32 len)
{
	if (len <= MSG_MAX_SIZE)
	{
		if (m_isConnect && m_buffer && m_fd)
		{
			int ret = bufferevent_write(m_buffer, data, len);
			return ret == 0;
		}
		//if (m_isConnect && m_fd)
		//{
		//	send(m_fd, (const char*)data, len, 0);
		//	return true;
		//}
	}
	return false;
}

void ssLeSession::Close()
{
	if (m_fd)
	{
		evutil_closesocket(m_fd);
		m_fd = 0;
	}
	if (m_buffer)
	{
		bufferevent_free(m_buffer);
		m_buffer = 0;
	}
	m_pServer = 0;
	m_sessionID = 0;
	m_isConnect = false;
}

char* ssLeSession::BevRead(evbuffer *input, u32 len)
{
	if (m_timeCheck)
	{
		i64 now = ssTime::GetTimeNowMS().i64p;
		if (now - m_lastTime < m_intervalTime)//太频繁
		{
			++m_fastCount;
		}
		else
		{
			m_fastCount = 0;
		}
		m_lastTime = now;
		if (m_fastCount > m_checkCount)//超过40次断线
		{
			OnTimeCheck(m_fastCount);
			return 0;
		}
	}
	if (!m_buffer || input == 0 || len == 0)
	{
		return 0;
	}
	//分析数据包
	if (m_pServer->GetParsePackageMode()==1)
	{
		return ParseData(input);
	}
	else
	{
		char* tempBuff = new char[len+4];
		bufferevent_read(m_buffer, tempBuff, len);
		return tempBuff;
	}
}

void ssLeSession::OnTimeCheck(u16 fastCount)
{
	//!!需要对象池
	Close();
	//通知上层
	//OnClose(SS_CONNECT_FAST)；
	return;
}

char* ssLeSession::ParseData(evbuffer *input)
{
	u32 runCt = 0;
	while (runCt++<300)
	{
		ssNetMsgHead head(0, 0);
		//memset(&head, 0, sizeof(ssNetMsgHead));
		u32 howMuch = evbuffer_get_length(input);
		if (howMuch < sizeof(ssNetMsgHead))
		{
			break;
		}
		evbuffer_copyout(input, &head, sizeof(ssNetMsgHead));
		//check msg
		if (head.m_dwTcpFlag != MSG_HEADER_FLAG || head.m_dwLen >= MSG_MAX_SIZE || head.m_dwLen < sizeof(ssNetMsgHead))
		{
			if (m_buffer != NULL)
			{
				void* tempBuff = ::malloc(howMuch + 8);
				bufferevent_read(m_buffer, tempBuff, howMuch);
				::free(tempBuff);
				break;
			}
		}
		if (howMuch < head.m_dwLen)
		{
			break;
		}
		//!!需要对象池
		if (m_buffer != NULL)
		{
			char* tempBuff = new char[head.m_dwLen * 2];
			size_t size = bufferevent_read(m_buffer, tempBuff, head.m_dwLen);
			if ((size == head.m_dwLen) && (size < MSG_MAX_SIZE) && m_pServer)
			{
				//抛到上层
				ssNetMsgHead* headData = (ssNetMsgHead*)tempBuff;
				//m_pNetworkMgr->PostMsg(SS_MSG_RECRIVE, head.m_dwMsgID, m_sessionID, (ulint)tempBuff, 0);
				return tempBuff;
			}
			else
			{
				//回收内存
				delete[] tempBuff;
			}
		}
	}
	return 0;
}

void ssLeSession::PostClose(u32 reason)
{
	m_isConnect = false;
}

}
